package org.proxycine.gestsalles.web.beans;

import java.io.Serializable;
import java.sql.Time;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.primefaces.component.tabview.TabView;
import org.primefaces.event.TabChangeEvent;
import org.proxycine.gestsalles.model.entities.Copie;
import org.proxycine.gestsalles.model.entities.Film;
import org.proxycine.gestsalles.model.entities.Format_seance;
import org.proxycine.gestsalles.model.entities.Langue_seance;
import org.proxycine.gestsalles.model.entities.Salle;
import org.proxycine.gestsalles.model.entities.Seance;
import org.proxycine.gestsalles.services.CopieService;
import org.proxycine.gestsalles.services.FilmService;
import org.proxycine.gestsalles.services.SalleService;
import org.proxycine.gestsalles.services.SeanceService;

@ManagedBean(name = "insererSeanceBean")
@ViewScoped
public class InsererSeanceBean implements Serializable {

	/**
         * 
         */
	private static final long serialVersionUID = 1L;
	private LoginBean loginBean;
	private String loginGerant;
	private List<Film> filmsDropped;

	private List<Salle> sallesDuCinema;
	private List<Film> filmsAchetesPourUnCinema;
	private List<Seance> listeSeances;

	private int numeroSalleSelected = 16;
	private int heureSelected = 0;

	private String film_name_create = "";
	private java.util.Date debutSeance_create;
	private java.util.Date date_seance_create;
	private String langue_create;
	private String format_create;
	public boolean updateSeance = false;

	private Seance seanceSelected = null;

	private String errorMsg = "";
	private boolean seanceCreated = false;

	private List<Date> listeDates;
	private String selectedDate;

	private int ecartSeances = 15;

	public InsererSeanceBean() {

		FacesContext ctx = FacesContext.getCurrentInstance();
		loginBean = (LoginBean) ctx
				.getApplication()
				.getExpressionFactory()
				.createValueExpression(ctx.getELContext(), "#{loginBean}",
						LoginBean.class).getValue(ctx.getELContext());
		loginGerant = loginBean.getLogin();

		filmsDropped = new ArrayList<Film>();

		this.sallesDuCinema = SalleService.getInstance().getScreensFromACinema(
				loginGerant);

		// Récupération des séances pour ce cinéma
		this.listeSeances = SeanceService.getInstance()
				.getProjectionsForLoggedManager(loginGerant);

		// On recupere les films attribués a un cinéma, grce au login du gérant
		filmsAchetesPourUnCinema = FilmService.getInstance().getAffectedFilms(
				loginGerant);

		this.listeDates = new ArrayList<Date>();

		Calendar calendar = Calendar.getInstance();
		for (int i = 1; i < 8; i++) {
			calendar.add(Calendar.DATE, 1);
			listeDates.add(calendar.getTime());
		}
	}

	public String getFormatedDate(java.util.Date d) {
		DateFormat dateFormat = new SimpleDateFormat("dd/MM");
		return dateFormat.format(d);
	}

	@SuppressWarnings("deprecation")
	public void insertListener(ActionEvent actionEvent) {

		if (film_name_create != null && date_seance_create != null
				&& langue_create != null && format_create != null) {

			if (debutSeance_create != null) {
				Film filmChevauche = isHoraireOk(date_seance_create,
						debutSeance_create, film_name_create);
				if (filmChevauche == null) {
					System.out.println("name : " + film_name_create);
					System.out.println("salle : " + numeroSalleSelected);
					System.out.println("debut seance : "
							+ Time.valueOf(debutSeance_create.getHours() + ":"
									+ debutSeance_create.getMinutes() + ":"
									+ debutSeance_create.getSeconds()));
					System.out.println("date : "
							+ new java.sql.Date(date_seance_create.getTime()));
					System.out.println("langue : " + langue_create);
					System.out.println("format : "
							+ Format_seance.valueOf(format_create).toString());

					// Insertion de la séance en DB
					insererSeance(
							film_name_create,
							numeroSalleSelected,
							Time.valueOf(debutSeance_create.getHours() + ":"
									+ debutSeance_create.getMinutes() + ":"
									+ debutSeance_create.getSeconds()),
							new java.sql.Date(date_seance_create.getTime()),
							langue_create, Format_seance.valueOf(format_create));

					this.seanceCreated = true;
					this.errorMsg = "Séance bien créée";

					film_name_create = null;
					debutSeance_create = null;
					date_seance_create = null;
					langue_create = null;
					format_create = null;
				} else {
					this.seanceCreated = false;
					this.errorMsg = "L'horaire sélectionnée chevauche avec le film : "
							+ filmChevauche.getTitre()
							+ " (Pensez à prendre en compte l'écart de "
							+ ecartSeances + " minutes entre les séances)";
				}
			} else {
				this.seanceCreated = false;
				this.errorMsg = "Veuillez sélectionner l'horaire";
			}
		} else {
			this.seanceCreated = false;
			this.errorMsg = "Erreur lors de la création de la séance";
		}
	}

	public Film isHoraireOk(java.util.Date dateSeance,
			java.util.Date heureSeance, String film_name) {
		Film f = null;

		int dureeFilm = FilmService.getInstance().getFilm(film_name).getDuree();
		for (Seance s : listeSeances) {
			if (getZeroTimeDate(s.getDate_seance()).compareTo(
					getZeroTimeDate(dateSeance)) == 0
					&& numeroSalleSelected == s.getSalle().getNumero_salle()) {

				// If debut1 <= fin2 && fin1 >= debut2
				if ((calPlusMinutes(s.getDebut_seance(), 0)
						.compareTo(calPlusMinutes(heureSeance, dureeFilm
								+ ecartSeances))) <= 0

						&&

						(calPlusMinutes(s.getDebut_seance(), s.getCopie()
								.getFilm().getDuree())
								.compareTo(calPlusMinutes(heureSeance,
										-ecartSeances))) >= 0) {

					f = s.getCopie().getFilm();
					break;
				}
			}
		}

		return f;
	}

	@SuppressWarnings("deprecation")
	public Calendar calPlusMinutes(Date heureDebut, int minutesAajouter) {
		Calendar cal = Calendar.getInstance();
		cal.set(2000, 01, 01, heureDebut.getHours(), heureDebut.getMinutes());
		// cal.setTime(heureDebut);
		cal.add(Calendar.MINUTE, minutesAajouter);

		return cal;
	}

	public Date getZeroTimeDate(Date fecha) {
		Date res = fecha;
		Calendar calendar = Calendar.getInstance();

		calendar.setTime(fecha);
		calendar.set(Calendar.HOUR_OF_DAY, 0);
		calendar.set(Calendar.MINUTE, 0);
		calendar.set(Calendar.SECOND, 0);
		calendar.set(Calendar.MILLISECOND, 0);

		res = calendar.getTime();

		return res;
	}

	public void clearData() {
		film_name_create = null;
		debutSeance_create = null;
		date_seance_create = null;
		langue_create = null;
		format_create = null;
		errorMsg = "";
	}

	public int getAccordionIndex(int numeroSalle) {
		int i = 0;
		for (Salle salle : sallesDuCinema) {
			if (salle.getNumero_salle() == numeroSalle) {
				break;
			}
			i++;
		}

		return i;
	}

	public Seance insererSeance(String film_name, int numero_salle,
			Time debutSeance, java.sql.Date date_seance, String langue,
			Format_seance format) {
		Copie copie = CopieService.getInstance().getCopieFromFilmName(
				film_name, loginGerant);
		Salle salle = SalleService.getInstance().getSalleFromLogin(loginGerant,
				numero_salle);

		Seance s = SeanceService.getInstance()
				.insertSeance(copie, salle, debutSeance, date_seance,
						Langue_seance.valueOf(langue), format);
		this.listeSeances.add(s);

		return s;
	}

	public void removeSelectedSeance() {
		this.listeSeances.remove(this.seanceSelected);
		SeanceService.getInstance().removeSeance(this.seanceSelected.getId());
		this.seanceSelected = null;
	}

	public List<String> getNamesFilmsAchetesPourUnCinema() {
		List<String> names = new ArrayList<String>();

		for (Film f : filmsAchetesPourUnCinema)
			names.add(f.getTitre());

		return names;
	}

	public void removeFilmAvailble(String titre) {
		Film toRemove = null;

		for (Film f : filmsAchetesPourUnCinema) {
			if (f.getTitre().equals(titre)) {
				toRemove = f;
				break;
			}
		}

		if (toRemove != null)
			filmsAchetesPourUnCinema.remove(toRemove);

		for (Film f : filmsAchetesPourUnCinema) {
			System.out.println(f.getTitre());
		}
	}

	public boolean dateEquals(java.util.Date date1, java.util.Date date2) {
		DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		return dateFormat.format(date1).equals(dateFormat.format(date2));
	}

	public List<Film> getFilmsDropped() {
		return filmsDropped;
	}

	public void setFilmsDropped(List<Film> filmsDropped) {
		this.filmsDropped = filmsDropped;
	}

	public List<Salle> getSallesDuCinema() {
		return sallesDuCinema;
	}

	public List<Film> getFilmsAchetesPourUnCinema() {
		return filmsAchetesPourUnCinema;
	}

	public int getNumeroSalleSelected() {
		return numeroSalleSelected;
	}

	public void setDataSelected(int numeroSalleSelected, java.util.Date date,
			boolean update) {
		this.numeroSalleSelected = numeroSalleSelected;
		this.date_seance_create = date;
		this.updateSeance = update;
	}

	public void setNumeroSalleSelected(int numeroSalleSelected) {
		this.numeroSalleSelected = numeroSalleSelected;
	}

	public int getHeureSelected() {
		return heureSelected;
	}

	public void setHeureSelected(int heureSelected) {
		this.heureSelected = heureSelected;
	}

	public String getFilm_name_create() {
		return film_name_create;
	}

	public void setFilm_name_create(String film_name_create) {
		this.film_name_create = film_name_create;
	}

	public java.util.Date getDebutSeance_create() {
		return debutSeance_create;
	}

	public void setDebutSeance_create(java.util.Date debutSeance_create) {
		this.debutSeance_create = debutSeance_create;
	}

	public java.util.Date getDate_seance_create() {
		return date_seance_create;
	}

	public void setDate_seance_create(java.util.Date date_seance_create) {
		this.date_seance_create = date_seance_create;
	}

	public String getLangue_create() {
		return langue_create;
	}

	public void setLangue_create(String langue_create) {
		this.langue_create = langue_create;
	}

	public String getFormat_create() {
		return format_create;
	}

	public void setFormat_create(String format_create) {
		this.format_create = format_create;
	}

	public List<Seance> getListeSeances() {
		return listeSeances;
	}

	public List<Seance> getListeSeances(java.util.Date date) {

		System.out.println(date.toString());

		List<Seance> list = new ArrayList<Seance>();
		for (Seance s : listeSeances) {
			if (s.getDate_seance().equals(date)) {
				list.add(s);
			}
		}

		return list;
	}

	public void setListeSeances(List<Seance> listeSeances) {
		this.listeSeances = listeSeances;
	}

	public String getErrorMsg() {
		return errorMsg;
	}

	public void setErrorMsg(String errorMsg) {
		this.errorMsg = errorMsg;
	}

	public boolean isSeanceCreated() {
		return seanceCreated;
	}

	public void setSeanceCreated(boolean seanceCreated) {
		this.seanceCreated = seanceCreated;
	}

	public List<Date> getListeDates() {
		return listeDates;
	}

	public void setListeDates(List<Date> listeDates) {
		this.listeDates = listeDates;
	}

	public String getSelectedDate() {
		return selectedDate;
	}

	public void setSelectedDate(String selectedDate) {
		this.selectedDate = selectedDate;
	}

	public Seance getSeanceSelected() {
		return seanceSelected;
	}

	public void setSeanceSelected(Seance seanceSelected, boolean update) {
		this.seanceSelected = seanceSelected;
		this.updateSeance = update;

		this.film_name_create = seanceSelected.getCopie().getFilm().getTitre();
		this.debutSeance_create = seanceSelected.getDebut_seance();
		this.date_seance_create = seanceSelected.getDate_seance();
		this.langue_create = seanceSelected.getLangue().name();
		this.format_create = seanceSelected.getFormat().name();
	}
}